﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "resource.h"
#include "network.h"
#include "ServerLoader.h"
#include "ServiceDlg.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CServiceDlg
XBEGIN_DLG_ID_WND_EXCHANGE( CServiceDlg )
XDLG_ID_WND( IDC_CONNECT_MASTER,    m_ConnectMaster )
XDLG_ID_WND( IDC_CONNECT_MASTERDB,  m_ConnectMasterDB )
XDLG_ID_WND( IDC_SERVICE_IDS,       m_RoutineIds )
XDLG_ID_WND( IDC_SERVICE_INFO,      m_ServerInfo )
XDLG_ID_WND( IDD_SERVICE,           m_Service )
XEND_DLG_ID_WND_EXCHANGE( CXDlg )

CServiceDlg::CServiceDlg(void)
: m_uServiceOnline(0)
, m_uServiceTotal(0)
, m_uServiceLoad(0)
, m_uMasterId(0)
, m_uRoutineIds(0)
{
}

CServiceDlg::~CServiceDlg(void)
{
}

LRESULT CServiceDlg::OnInitDialog(void)
{
    RECT rc;
    GetClientRect(&rc);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);

    m_Service.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));
    //
    CStringFix strTemp;
    strTemp.Load(IDC_CONNECT_MASTER);
    m_ConnectMaster.SetWindowText(*strTemp);

    strTemp.Load(IDC_CONNECT_MASTERDB);
    m_ConnectMasterDB.SetWindowText(*strTemp);

    strTemp.Load(IDC_SERVICE_IDS);
    m_RoutineIds.SetWindowText(*strTemp);
    //
    InitServerData(PAKT_SERVICE + PAKT_MAX);
    return TRUE;
}

LRESULT CServiceDlg::OnSize(WPARAM, LPARAM lParam, BOOL&)
{
    RECT rc   = { 0 };
    rc.right  = (Long)LOWORD(lParam);
    rc.bottom = (Long)HIWORD(lParam);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_ServerInfo.MoveWindow(0, rc.top, rc.right, DLG_ITEM_HEIGHT);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_Service.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));

    rc.right /=2;
    if (rc.right > DLG_ITEM_WIDTH)
    {
        m_ConnectMaster.MoveWindow(0, 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
        m_ConnectMasterDB.MoveWindow((rc.right + DLG_ITEM_GRAP), 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
    }
    return 0;
}

void CServiceDlg::OnLive(bool bStart)
{
    CStringFix strTemp;
    if (bStart)
    {
    }
    else
    {
        strTemp.Load(IDC_CONNECT_MASTER);
        m_ConnectMaster.SetWindowText(*strTemp);

        strTemp.Load(IDC_CONNECT_MASTERDB);
        m_ConnectMasterDB.SetWindowText(*strTemp);

        strTemp.Load(IDC_SERVICE_IDS);
        m_RoutineIds.SetWindowText(*strTemp);

        m_uServiceOnline = 0;
        m_uServiceTotal  = 0;
        m_uServiceLoad   = 0;
        m_uMasterId      = 0;
        m_uRoutineIds    = 0;
    }
    m_ServerInfo.SetWindowText(TF(""));
}

void CServiceDlg::OnLink(Int nServerIndex, uintptr_t utData)
{
    CStringFix strTemp;
    if (nServerIndex == PAKT_MASTER)
    {
        strTemp.Load(IDC_CONNECT_MASTER);

        CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

        CStrAddr strAddr;
        GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_MASTER, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

        GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
        strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);

        m_ConnectMaster.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_MASTERDB)
    {
        strTemp.Load(IDC_CONNECT_MASTERDB);

        if (utData != 0)
        {
            CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

            CStrAddr strAddr;
            GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_MASTERDB, CServerConfig::CFG_LOAD_NONE, strAddr);
            strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

            GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
            strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);
        }
        else
        {
            CStringFix strLoad;
            strLoad.Load(IDS_NONE_MARK);
            strTemp += strLoad;
        }
        m_ConnectMasterDB.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_SERVICE)
    {
        CString strRId = reinterpret_cast<PCXStr>(utData);
        ULLong ullHash = CHash::Hash64(*strRId);
#ifdef _DEBUG
        LVFINDINFO find = {0};
        find.flags  = LVFI_PARAM;
        find.lParam = (LPARAM)(ullHash);
        assert(m_Service.FindItem(&find) == -1);
#endif
        Int nIndex = m_Service.GetItemCount();
        nIndex = m_Service.InsertItem(nIndex, *strRId);
        if (nIndex >= 0)
        {
            strRId.Format(TF("%llX"), ullHash);
            m_Service.SetItemText(nIndex, 1, *strRId);

            strRId.Load(IDS_NONE_MARK);
            m_Service.SetItemText(nIndex, 2, *strRId);

            m_Service.SetItemData(nIndex, (uintptr_t)ullHash);
        }
    }
    else if (nServerIndex == PAKT_SERVICE_MASTER)
    {
        CString strRId = reinterpret_cast<PCXStr>(utData);

        ULLong ullHash = FALSE;
        for (size_t i = 0; i < strRId.Length(); ++i)
        {
            if (strRId.IsXDigitChar(i))
            {
                ullHash = TRUE;
                break;
            }
        }
        ullHash = strRId.ToULLong((ullHash == TRUE) ? RADIXT_HEX : RADIXT_DEC);
#ifdef _DEBUG
        LVFINDINFO find = {0};
        find.flags  = LVFI_PARAM;
        find.lParam = (LPARAM)(ullHash);
        assert(m_Service.FindItem(&find) == -1);
#endif
        Int nIndex = m_Service.GetItemCount();
        nIndex = m_Service.InsertItem(nIndex, *strRId);
        if (nIndex >= 0)
        {
            strRId.Format(TF("%llX"), ullHash);
            m_Service.SetItemText(nIndex, 1, *strRId);

            strRId.Load(IDS_NONE_MARK);
            m_Service.SetItemText(nIndex, 2, *strRId);

            m_Service.SetItemData(nIndex, (uintptr_t)ullHash);
        }
    }
}

void CServiceDlg::OnUpdate(Int nLinkAck, uintptr_t utData)
{
    LVFINDINFO find = {0};
    find.flags  = LVFI_PARAM;
    find.lParam = (LPARAM)(utData);
    Int nIndex  = m_Service.FindItem(&find);
    if (nIndex > -1)
    {
        CStringFix strTemp;
        if (nLinkAck == 0)
        {
            strTemp.Load(IDS_ROUTINE_ID_ONLINE);
        }
        else
        {
            strTemp.Load(IDS_ROUTINE_ID_ERROR);
            strTemp.AppendFormat(TF("%d"), nLinkAck);
        }
        m_Service.SetItemText(nIndex, 2, *strTemp);
    }
}

void CServiceDlg::OnSync(Int nServerIndex, uintptr_t utData)
{
    if (nServerIndex == PAKT_SERVICE)
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uServiceTotal   = pStatus->uTotal;
        m_uServiceOnline  = pStatus->uOnline;
        m_uServiceLoad    = pStatus->usLoad;
    }
    else if (nServerIndex == PAKT_MASTER)
    {
        m_uMasterId       = (UInt)utData;
        if (utData == 0)
        {
            CStringFix strTemp;
            strTemp.Load(IDS_ROUTINE_ID_OFFLINE);
            for (Int i = 0; i < m_Service.GetItemCount(); ++i)
            {
                m_Service.SetItemText(i, 2, *strTemp);
            }
        }
    }
    else
    {
        m_uRoutineIds     = (UInt)utData;

        CStringFix strTemp;
        strTemp.Load(IDC_SERVICE_IDS);
        strTemp.AppendFormat(TF("%d"), m_uRoutineIds);
        m_RoutineIds.SetWindowText(*strTemp);
    }
}

void CServiceDlg::OnSync(Int, CStream&)
{
}

void CServiceDlg::OnUnlink(Int nServerIndex, uintptr_t utData)
{
    CStringFix strTemp;
    if (nServerIndex == PAKT_MASTER)
    {
        strTemp.Load(IDC_CONNECT_MASTER);
        m_ConnectMaster.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_MASTERDB)
    {
        strTemp.Load(IDC_CONNECT_MASTERDB);
        m_ConnectMasterDB.SetWindowText(*strTemp);
    }
}

void CServiceDlg::UpdateServerInfo(void)
{
    CStringFix strInfo;
    strInfo.Load(IDC_SERVICE_INFO);

    CStringFix strTemp;
    strTemp.Format(*strInfo, m_uServiceOnline, m_uServiceTotal, m_uMasterId);
    m_ServerInfo.SetWindowText(*strTemp);
}

CXListView* CServiceDlg::GetListView(Int nServerIndex)
{
    UNREFERENCED_PARAMETER(nServerIndex);
    assert(nServerIndex == (PAKT_SERVICE + PAKT_MAX));
    return &m_Service;
}




